package com.stars.easyms.base.asynchronous;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>className: BaseAsynchronousTask</p>
 * <p>description: 异步线程处理数据的基础类</p>
 *
 * @author guoguifang
 * @date 2019/8/22 16:32
 * @since 1.3.0
 */
public abstract class BaseAsynchronousTask<T> extends AbstractAsynchronousTask<T> {

    /**
     * 为每一个单条处理的方法建立一个独立的事务
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = {Exception.class})
    public boolean doExecute(T t) throws Exception {
        return execute(t);
    }

    /**
     * 异步处理数据的方法
     *
     * @param t 待处理的数据
     * @return true:处理成功,false:处理失败
     * @throws Exception 异常
     */
    protected abstract boolean execute(T t) throws Exception;

    @Override
    void handleQueue(boolean isCore) {
        T t = dequeue(isCore);
        while (t != null) {
            try {
                boolean flag = doExecute(t);
                if (!flag) {
                    addErrorData(0, t);
                }
            } catch (Exception e) {
                addErrorData(0, t);
                logger.error("执行异步任务失败!", e);
            }
            t = dequeue(isCore);
        }
    }

    @Override
    void handleErrorData(T t, int failCount) {
        try {
            boolean flag = doExecute(t);
            if (!flag) {
                if (failCount < failRetryCount - 1) {
                    addErrorData(failCount + 1, t);
                } else {
                    failedDiscardCount.increment();
                }
            }
        } catch (Exception e) {
            logger.error("执行异步任务失败!", e);
            if (failCount < failRetryCount - 1) {
                addErrorData(failCount + 1, t);
            } else {
                failedDiscardCount.increment();
            }
        }
    }

    @Override
    void batchHandleErrorData(List<T> list, int failCount, boolean isCheckSize) {
        // Intentionally blank
    }
}
